var tgd = tgd || {};
tgd.Media = tgd.Media || {};


tgd.Media.MediaLibrary = function (callback) {

    var db;

    db = openDatabase("MediaLibrary", "1.0", "Maverick Mindless Drones - Media Library", 5 * 1024 * 1024);
    db.transaction(function(t) {
        t.executeSql('CREATE TABLE IF NOT EXISTS library (ID, Name, DateCreated DEFAULT (CURRENT_TIMESTAMP), CreatedBy DEFAULT (\'\'))', null, function(t, rs) { if (rs.rowsAffected == 1) { alert('Library Table Created!'); } }, function(t, err) { alert(err.message); });
        t.executeSql('CREATE TABLE IF NOT EXISTS entry (ID, LibraryID, Name, UPC, ThumbURL, NameSource, CreatedBy DEFAULT (\'\'), DateCreated DEFAULT (CURRENT_TIMESTAMP))', null, function(t, rs) { if (rs.rowsAffected == 1) { alert('Entry Table Created!'); } }, function(t, err) { alert(err.message); });
    });

    var dat = [];
    var _googleCallback;

    var self = this;

    tgd.Services.Google.Search.onResultsReturned = function (results) {
        var entry = self.getEntryByUPC(results.UPC);
        entry.setGoogleData(results);
        _googleCallback(entry);
    }

    this.setGoogleCallback = function(callback) {
        _googleCallback = callback;
    }

    this.getLibraries = function(callback) {
        return dat;
    }

    /*
     * returns Library object or null
     */
    this.getCurrentLibrary = function() {  //todo: have private variable pointing to current lib for performance
        var lib = null;

        if (window.localStorage.LibraryID === undefined) {
            return null;
        }

        for (var i = 0; i < dat.length; ++i) {
            if (dat[i].getID() === window.localStorage.LibraryID) {
                lib = dat[i];
                break;
            }
        }

        return lib;
    }

    /*
     * returns true if library for given ID exists, false otherwise
     */
    this.setCurrentLibraryID = function(id) {
        var libExists = false;

        for (var i = 0; i < dat.length; ++i) {
            if (dat[i].getID() === id) {
                window.localStorage.LibraryID = id
                libExists = true;
                break;
            }
        }

        return libExists;
    }

    this.addLibrary = function(lib, callback) {
        dat.push(lib);
        db.transaction(
            function(t) {
                t.executeSql("INSERT INTO library (ID, Name) values (?, ?)",
                    [lib.getID(), lib.getName()],
                    function(t, data) {
                        callback({ Status : 1, Message : "Inserted new library [" + lib.getID() + "]  [" + lib.getName() + "]." });
                    }, function(t, data) {
                        callback({ Status : 0, Message : "Error inserting library [" + lib.getID() + "]  [" + lib.getName() + "].  " + data.message })
                    }
                );
            }
        );
    }

    this.getLibraryByID = function(id) {
        var lib = null;
        for (var i = 0; i < dat.length; ++i) {
            if (dat[i].getID() === id) {
                lib = dat[i];
                break;
            }
        }

        if (lib === null) {
            throw new Error("Library #" + id + " not found.");
        }

        return lib;
    }
    
    this.getEntryByUPC = function(upc) {
        var entry;
        
        for (var i = 0; i < dat.length; ++i) {
            for (var j = 0; j < dat[i].getEntries().length; ++j) {
                if (dat[i].getEntries()[j].getUPC() === upc) {
                    entry = dat[i].getEntries()[j];
                    break;
                }
            }
        }

        return entry;
    }

    this.getGoogleData = function(upc) {
        var entry = this.getEntryByUPC(upc);
        if (entry.getGoogleData() === undefined) {
            tgd.Services.Google.Search.getUPC(upc);
        } else {
            _googleCallback(entry);
        }
    }

    //todo: handle errors.
    //todo:  see if db.transaction has a final callback, otherwise use the crazy select below.
    var self = this;
    db.transaction(
        function(t) {
            //t.executeSql("SELECT l.ID AS 'LibraryID', l.Name AS 'LibraryName', e.Name AS 'EntryName', e.UPC, e.ThumbURL FROM library AS l LEFT JOIN entry AS e ON l.ID = e.LibraryID ORDER BY l.ID",
            t.executeSql("SELECT ID, Name FROM library",
                null,
                function(t, data) {
                    for (var i = 0; i < data.rows.length; ++i) {
                        var library = new tgd.Media.Library(data.rows.item(i).ID, data.rows.item(i).Name)
                        dat.push(library);
                        
                        t.executeSql("SELECT Name, UPC, ThumbURL, LibraryID FROM entry WHERE LibraryID = ?",
                            [library.getID()],
                            function(t, data2) {
                                for (var j = 0; j < data2.rows.length; ++j) {
                                    self.getLibraryByID(data2.rows.item(j).LibraryID).addEntry(new tgd.Media.Entry({ LibraryID : data2.rows.item(j).LibraryID, Name : data2.rows.item(j).Name, UPC : data2.rows.item(j).UPC, ThumbURL : data2.rows.item(j).ThumbURL }), function() {});
                                }
                            }
                        );
                    }
                }
            );
        },
        function(err) {
            callback({ Status : 0, Message : err.Message });
        },
        function() {
            callback({ Status : 1, Message : "Data loaded." });
        }
    );
}
